package microcredit.gui.editor.group;

import java.awt.Component;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JTextArea;
import javax.swing.JTextField;

import microcredit.gui.editor.AbstractEditorForm;
import microcredit.gui.handler.MemberHandler.ByGroupMemberHandler;
import microcredit.gui.util.FixedLengthDocument;
import microcredit.gui.util.MemberEditorField;
import microcredit.gui.util.UIUtil;
import microcredit.model.Member;
import microcredit.model.MemberGroup;
import microcredit.model.domain.Status;
import net.miginfocom.swing.MigLayout;

public class GroupGeneralForm extends AbstractEditorForm<MemberGroup> {
 
	private JLabel shortNameLabel;
	private JLabel nameLabel;
	private JTextField shortNameTextField;
	private JTextField nameTextField;
	private JLabel chairmanLabel;
	private JLabel secretaryLabel;
	private JLabel tresurerLabel;
	private JLabel meetingsTextLabel;
	private JTextArea meetingsTextArea;
	private MemberEditorField chairmanEditorField;
	private MemberEditorField secretaryMemberField;
	private MemberEditorField tresurerMemberField;
	
	private final RestrictedMemberHandler tresurerMemberHandler = new RestrictedMemberHandler(null);
	private final RestrictedMemberHandler secretaryMemberHandler = new RestrictedMemberHandler(null);
	private final RestrictedMemberHandler chairmanMemberHandler = new RestrictedMemberHandler(null);
	
	private JCheckBox activeCheckBox;
	
	public GroupGeneralForm() {
		initialize();
		setTitle("General");
		UIUtil.setMandatoryFields(this, MemberGroup.SHORT_NAME, MemberGroup.NAME);
	}
	
	@Override
	public void focusDefault() {
		getShortNameTextField().requestFocus();
		getShortNameTextField().selectAll();
	}
	
	@Override
	public MemberGroup receive(MemberGroup element) {
		element.setName(getNameTextField().getText());
		element.setShortName(getShortNameTextField().getText());
		element.setMeetingsText(getMeetingsTextArea().getText());
		
		element.setSecretaryMember(getSecretaryMemberField().getElement());
		element.setTresurerMember(getTresurerMemberField().getElement());
		element.setChairmanMember(getChairmanEditorField().getElement());
		element.setStatus(getActiveCheckBox().isSelected() ? Status.A : Status.I);
		
		return element;
	}

	@Override
	public void apply(MemberGroup element) {
		tresurerMemberHandler.setMemberGroup(element);
		secretaryMemberHandler.setMemberGroup(element);
		chairmanMemberHandler.setMemberGroup(element);
		
		getNameTextField().setText(element.getName());
		getShortNameTextField().setText(element.getShortName());
		getMeetingsTextArea().setText(element.getMeetingsText());
		
		getTresurerMemberField().setElement(element.getTresurerMember());
		getChairmanEditorField().setElement(element.getChairmanMember());
		getSecretaryMemberField().setElement(element.getSecretaryMember());
		
		getActiveCheckBox().setSelected(element.getStatus() == Status.A);
	}
	
	private void initialize() {
		setLayout(new MigLayout("", "[][grow,fill]", "[][][][][baseline][][grow,fill][]"));
		add(getActiveCheckBox(), "cell 1 0");
		add(getShortNameLabel(), "cell 0 1,alignx trailing");
		add(getShortNameTextField(), "cell 1 1,growx");
		add(getNameLabel(), "cell 0 2,alignx trailing");
		add(getNameTextField(), "cell 1 2,growx");
		add(getChairmanLabel(), "cell 0 3,alignx trailing");
		add(getChairmanEditorField(), "cell 1 3,growx");
		add(getSecretaryLabel(), "cell 0 4,alignx trailing");
		add(getSecretaryMemberField(), "cell 1 4,grow");
		add(getTresurerLabel(), "cell 0 5,alignx trailing");
		add(getTresurerMemberField(), "cell 1 5,grow");
		add(getMeetingsTextLabel(), "cell 0 6");
		add(getMeetingsTextArea(), "cell 1 6");
	}

	private JLabel getShortNameLabel() {
		if (shortNameLabel == null) {
			shortNameLabel = new JLabel("Short name");
			shortNameLabel.setName("shortNameLabel");
		}
		return shortNameLabel;
	}
	private JLabel getNameLabel() {
		if (nameLabel == null) {
			nameLabel = new JLabel("Name");
			nameLabel.setName("nameLabel");
		}
		return nameLabel;
	}
	private JTextField getShortNameTextField() {
		if (shortNameTextField == null) {
			shortNameTextField = new JTextField();
			shortNameTextField.setName(MemberGroup.SHORT_NAME);
			shortNameTextField.setColumns(10);
			shortNameTextField.setDocument(new FixedLengthDocument(15));
		}
		return shortNameTextField;
	}
	private JTextField getNameTextField() {
		if (nameTextField == null) {
			nameTextField = new JTextField();
			nameTextField.setName(MemberGroup.NAME);
			nameTextField.setColumns(10);
			nameTextField.setDocument(new FixedLengthDocument(255));
		}
		return nameTextField;
	}
	private JLabel getChairmanLabel() {
		if (chairmanLabel == null) {
			chairmanLabel = new JLabel("Chairman");
			chairmanLabel.setName("chairmanLabel");
		}
		return chairmanLabel;
	}
	private JLabel getSecretaryLabel() {
		if (secretaryLabel == null) {
			secretaryLabel = new JLabel("Secretary");
			secretaryLabel.setName("secretaryLabel");
		}
		return secretaryLabel;
	}
	private JLabel getTresurerLabel() {
		if (tresurerLabel == null) {
			tresurerLabel = new JLabel("Tresurer");
			tresurerLabel.setName("tresurerLabel");
		}
		return tresurerLabel;
	}
	private JLabel getMeetingsTextLabel() {
		if (meetingsTextLabel == null) {
			meetingsTextLabel = new JLabel("General information");
			meetingsTextLabel.setName("meetingsTextLabel");
		}
		return meetingsTextLabel;
	}
	private JTextArea getMeetingsTextArea() {
		if (meetingsTextArea == null) {
			meetingsTextArea = new JTextArea();
			meetingsTextArea.setName("meetingsTextArea");
			meetingsTextArea.setDocument(new FixedLengthDocument(5000));
		}
		return meetingsTextArea;
	}

	private MemberEditorField getChairmanEditorField() {
		if (chairmanEditorField == null) {
			
			chairmanEditorField = new MemberEditorField( null, chairmanMemberHandler, chairmanMemberHandler, chairmanMemberHandler, chairmanMemberHandler);
			chairmanEditorField.setName(MemberGroup.CHAIRMAN_MEMBER);
			chairmanMemberHandler.setField(chairmanEditorField);
		}
		return chairmanEditorField;
	}
	private MemberEditorField getSecretaryMemberField() {
		if (secretaryMemberField == null) {
			
			secretaryMemberField = new MemberEditorField( null, secretaryMemberHandler, secretaryMemberHandler, secretaryMemberHandler, secretaryMemberHandler);
			secretaryMemberField.setName(MemberGroup.SECRETARY_MEMBER);
			secretaryMemberHandler.setField(secretaryMemberField);
		}
		return secretaryMemberField;
	}
	private MemberEditorField getTresurerMemberField() {
		if (tresurerMemberField == null) {
			
			tresurerMemberField = new MemberEditorField( null, tresurerMemberHandler, tresurerMemberHandler, tresurerMemberHandler, tresurerMemberHandler);
			tresurerMemberField.setName(MemberGroup.TRESURER_MEMBER);
			tresurerMemberHandler.setField(tresurerMemberField);
		}
		return tresurerMemberField;
	}
	
	private JCheckBox getActiveCheckBox() {
		if (activeCheckBox == null) {
			activeCheckBox = new JCheckBox("Active");
		}
		return activeCheckBox;
	}
	
	private class RestrictedMemberHandler extends ByGroupMemberHandler{

		private MemberEditorField field;
		
		public RestrictedMemberHandler(MemberGroup memberGroup) {
			super(GroupGeneralForm.this, memberGroup, true);
		}
		
		public void setField(MemberEditorField field) {
			this.field = field;
		}
		
		private List<Member> getMembers() {
			List<Member> members = new ArrayList<Member>();
			members.add(getTresurerMemberField().getElement());
			members.add(getChairmanEditorField().getElement());
			members.add(getSecretaryMemberField().getElement());
			return members;
		}
		
		@Override
		public List<Member> load() throws Throwable {
			List<Member> members= super.load();
			
			List<Member> filteredMembers = getMembers();
			
			if (field.getElement() != null) {
				filteredMembers.remove(field.getElement());
			}
			
			for (Iterator<Member> iterator = members.iterator(); iterator.hasNext();) {
				Member member = iterator.next();
				if (filteredMembers.contains(member)) {
					iterator.remove();
				}
			}
			
			return members;
		}
		
	}
	
	
}
